package name.elftesting.vncelf;

import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.text.BadLocationException;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

import name.elftesting.vnctest.LanguageTemplete;
import name.elftesting.vnctest.VncElf;

import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;

/**
 * 
 * @author Xiaoping Wu
 * 
 */
public class Chariotc {
	public static LanguageTemplete lt = null;

	public static void complie(String script, String fileName, final VncElf vr,
			 RSyntaxTextArea editor,JButton runButton) {
		File path=new File("");
		String tempPath=path.getAbsolutePath()+"\\temp";
		
		System.out.println(tempPath+"-----------------------");
		try {
			tempPath=java.net.URLDecoder.decode(tempPath,"utf-8");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}  

	
		File temp = new File(tempPath);
		if (!temp.exists() || !temp.isDirectory())
			temp.mkdir();
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
		StringWriter writer = new StringWriter();
		PrintWriter out = new PrintWriter(writer);
		out.println(script);

		out.close();
		JavaFileObject file = new JavaSourceFromString(fileName,
				writer.toString());
		Iterable<String> options = Arrays.asList("-d", tempPath);
		Iterable<? extends JavaFileObject> compilationUnits = Arrays
				.asList(file);
		CompilationTask task = compiler.getTask(null, null, diagnostics,
				options, null, compilationUnits);

		boolean success = task.call();
		int editorLine=editor.getLineCount();
		for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {

			vr.log(diagnostic.getCode() + " ", false);
			vr.log(diagnostic.getKind() + " ", false);
			vr.log(diagnostic.getPosition() + " ", false);

			long line = diagnostic.getLineNumber() - 9;
			runButton.setEnabled(true);
			vr.setStatusBar("Stop");
			try {
				if (line < (editorLine+ 1))
				editor.addLineHighlight((int) line, Color.green);

			} catch (BadLocationException e) {
				// TODO Auto-generated catch block
				
				e.printStackTrace();
			}

			String message = diagnostic.getMessage(null);

			message = message.replaceAll("string:(.*?).java", "");
			//vr.log("///" + message, false);
			vr.log("");

		}

		if (success) {
			Class<?> cls = null;

			try {
				
				TempClassLoader loader = new TempClassLoader();
		        loader.addFile(new File(tempPath)); 
		        cls=loader.loadClass(fileName);

				lt = (LanguageTemplete) cls.newInstance();
				try{
				lt.setElf(vr);
				
				PrintStream ps = new PrintStream(System.out){
					 public void println(String x) {
					        vr.log(x + "\n");
					      }
				};
			
				lt.run();
				
				runButton.setEnabled(true);
				vr.setStatusBar("Stop");
				}catch(Exception ex){
					runButton.setEnabled(true);
					vr.setStatusBar("Stop");
					StackTraceElement[] stm=ex.getStackTrace();
					if(lt.getElf()!=null){
				for(int i=0;i<stm.length;i++){
					if(stm[i].getClassName().indexOf("JavaTemplete")>-1){
						int line=stm[i].getLineNumber()-9;
						try {
							if (line < (editorLine+ 1)){
							editor.addLineHighlight((int) line, Color.red);
							vr.log(stm[i]);
							}
							
						} catch (BadLocationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				vr.log("Execute: failed");
				}
				
				}
				cls = null;
				lt = null;
				System.gc();

				File f = new File("temp");
				
				for (int i = 0; i < f.listFiles().length; i++) {
					File df = f.listFiles()[i];

					df.delete();
				}
			} catch (Exception e) {
				
				
				cls = null;
				lt = null;
				System.gc();
				File f = new File("temp");
				
				for (int i = 0; i < f.listFiles().length; i++) {
					File df = f.listFiles()[i];
					df.delete();
				}
				e.printStackTrace();
			}
		} else {
			vr.log("Complie: failed");
		}

	}
}

 class TempClassLoader extends URLClassLoader{
	 
    public TempClassLoader(URL[] urls) {
        super(urls);
    }
     
    public TempClassLoader(){
        super(new URL[]{});
    }
     
    public void addFile(File f) throws MalformedURLException{
        this.addURL(f.toURI().toURL());
        System.out.println("URL:" + f.toURI().toURL());
    }
     
}

class JavaSourceFromString extends SimpleJavaFileObject {
	final String code;

	JavaSourceFromString(String name, String code) {
		super(URI.create("string:///" + name.replace('.', '/')
				+ Kind.SOURCE.extension), Kind.SOURCE);
		this.code = code;
	}

	@Override
	public CharSequence getCharContent(boolean ignoreEncodingErrors) {
		return code;

	}
}
